/*
 * Copyright (c) 2007, Olof Naessen and Per Larsson
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 *
 *    * Redistributions of source code must retain the above copyright notice, 
 *      this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright notice, 
 *      this list of conditions and the following disclaimer in the documentation 
 *      and/or other materials provided with the distribution.
 *    * Neither the name of the Darkbits nor the names of its contributors may be 
 *      used to endorse or promote products derived from this software without 
 *      specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <guichan.hpp>

#include "levelselector.hpp"
#include "resourcehandler.hpp"
#include "guichan/allegro.hpp"
#include "levelhandler.hpp"

#include <iostream>
#include <sstream>

LevelSelector::LevelSelector()
{
	setFrameSize(0);
    mSelectedImage = ResourceHandler::getInstance()->getBitmap("hand.bmp");
    mSelected = -1;
    setWidth(300);
    setFocusable(true);

    addKeyListener(this);

	mGreyFont = new gcn::ImageFont(ResourceHandler::getInstance()->getRealFilename("fontsmallgrey.bmp"), 32, 126);
	mGreyFont->setGlyphSpacing(-1);
	mWhiteFont = new gcn::ImageFont(ResourceHandler::getInstance()->getRealFilename("fontsmall.bmp"), 32, 126);
	mWhiteFont->setGlyphSpacing(-1);
}

LevelSelector::~LevelSelector()
{
    delete mGreyFont;
    delete mWhiteFont;
}

void LevelSelector::draw(gcn::Graphics* graphics)
{
    gcn::AllegroGraphics* allegroGraphics = static_cast<gcn::AllegroGraphics*>(graphics);

	allegroGraphics->setColor(getForegroundColor());

	int i, fontHeight;
	int y = 0;

	fontHeight = getFont()->getHeight();

	for (i = 0; i < LevelHandler::getInstance()->getNumberOfLevels(); ++i)
	{
        LevelModel* levelModel = LevelHandler::getInstance()->getLevel(i);

        if (levelModel->starsCollectedUntilUnlocked > LevelHandler::getInstance()->getStarsCollected())
        {
            allegroGraphics->setFont(mGreyFont);
        }
        else
        {
            allegroGraphics->setFont(mWhiteFont);
        }

		allegroGraphics->drawText(levelModel->name, 16, y);

        std::string str;
        std::ostringstream info(str);
       

		info << " TIME ";

		if (levelModel->bestTime == -1)
		{
			info << "--:--:--";
		}
		else
		{
			int time = levelModel->bestTime;
			int minutes = (time / 50) / 60;
            
			if (minutes < 10)
			{
				info << "0" << minutes << ":";
			}
			else
			{
				info << minutes << ":";
			}
            
			int seconds = (time / 50) % 60;

			if (seconds < 10)
			{
				info << "0" << seconds << ":";
			}
			else
			{
				info << seconds << ":";
			}

			int hundredths = (time * 2) % 100;

			if (hundredths < 10)
			{
				info << "0" << hundredths;
			}
			else
			{
				info << hundredths;
			}
		}

		if (levelModel->starsCollectedUntilUnlocked <= LevelHandler::getInstance()->getStarsCollected())
		{
			info << "   ~ " << levelModel->numberOfCollectedStars << " / " << levelModel->numberOfStars;
		}
		else
		{
			info << "   ~ " << levelModel->starsCollectedUntilUnlocked << " Unlocks";
		}

        allegroGraphics->drawText(info.str(), 160, y); 

		if (i == mSelected)
		{
			if (isFocused())
			{
			        gcn::AllegroImage image(mSelectedImage, 0);
			        allegroGraphics->drawImage(&image, 0, 0, 0, y,
			                image.getWidth(), image.getHeight());
			}
		}

		y += fontHeight;
	}
}

void LevelSelector::adjustSize()
{
    setHeight(getFont()->getHeight() * LevelHandler::getInstance()->getNumberOfLevels());
    setWidth(300);
}

void LevelSelector::keyPressed(gcn::KeyEvent& keyEvent)
{
    gcn::Key key = keyEvent.getKey();

    if (key.getValue() == gcn::Key::ENTER || key.getValue() == gcn::Key::SPACE)
    {
        distributeActionEvent();
        keyEvent.consume();
    }
    else if (key.getValue() == gcn::Key::UP)
    {
        setSelected(mSelected - 1);

        if (mSelected == -1)
        {
            setSelected(0);
        }
        
        keyEvent.consume();
    }
    else if (key.getValue() == gcn::Key::DOWN)
    {
       
        setSelected(getSelected() + 1); 
        keyEvent.consume();
    }
}

void LevelSelector::logic()
{
    adjustSize();
}

int LevelSelector::getSelected()
{
    return mSelected;
}

void LevelSelector::setSelected(int selected)
{
    if (LevelHandler::getInstance()->getNumberOfLevels() == 0)
    {
        mSelected = -1;
    }
    else
    {
        if (selected < 0)
        {
            mSelected = -1;
        }
        else if (selected >= LevelHandler::getInstance()->getNumberOfLevels())
        {
            mSelected = LevelHandler::getInstance()->getNumberOfLevels() - 1;
        }
        else
        {
            mSelected = selected;
        }

        Widget *par = getParent();
        if (par == NULL)
        {
            return;
        }

        gcn::Rectangle scroll;

        if (mSelected < 0)
        {
            scroll.y = 0;
        }
        else
        {
            scroll.y = getFont()->getHeight() * mSelected;
        }

        scroll.height = getFont()->getHeight();
        par->showWidgetPart(this, scroll);
    }
}

